{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 匹配子图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "import tvm\n",
    "from tvm import relax\n",
    "from tvm.relax.backend.cuda.cublas import partition_for_cublas\n",
    "from tvm.relax.backend.cuda.cutlass import partition_for_cutlass\n",
    "from tvm.relax.dpl.pattern import (\n",
    "    is_op,\n",
    "    is_tuple_get_item,\n",
    "    make_fused_bias_activation_pattern,\n",
    "    wildcard,\n",
    ")\n",
    "from tvm.relax.transform import PatternCheckContext\n",
    "from tvm.script import ir as I\n",
    "from tvm.script import relax as R\n",
    "from tvm.script import tir as T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "@R.function\n",
    "def func(\n",
    "    x: R.Tensor((32, 8), dtype=\"int32\"),\n",
    "    y: R.Tensor((8, 8), dtype=\"int32\"),\n",
    "    bias: R.Tensor((8,), dtype=\"int32\"),\n",
    ") -> R.Tensor((32, 8), dtype=\"int32\"):\n",
    "    R.func_attr({\"global_symbol\": \"main\"})\n",
    "    with R.dataflow():\n",
    "        lv0 = R.matmul(x, y, out_dtype=\"int32\")\n",
    "        lv1 = R.add(lv0, bias)\n",
    "        lv2 = R.clip(lv1, -128, 127)\n",
    "        R.output(lv2)\n",
    "    return lv2\n",
    "\n",
    "mod = tvm.IRModule({\"main\": func})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"highlight\" style=\"background: \"><pre style=\"line-height: 125%;\"><span></span><span style=\"color: #007979; font-style: italic\"># from tvm.script import ir as I</span>\n",
       "<span style=\"color: #007979; font-style: italic\"># from tvm.script import relax as R</span>\n",
       "\n",
       "<span style=\"color: #AA22FF\">@I</span><span style=\"color: #AA22FF; font-weight: bold\">.</span>ir_module\n",
       "<span style=\"color: #008000; font-weight: bold\">class</span> <span style=\"color: #0000FF; font-weight: bold\">Module</span>:\n",
       "    <span style=\"color: #AA22FF\">@R</span><span style=\"color: #AA22FF; font-weight: bold\">.</span>function\n",
       "    <span style=\"color: #008000; font-weight: bold\">def</span> <span style=\"color: #0000FF\">main</span>(x: R<span style=\"color: #AA22FF; font-weight: bold\">.</span>Tensor((<span style=\"color: #008000\">32</span>, <span style=\"color: #008000\">8</span>), dtype<span style=\"color: #AA22FF; font-weight: bold\">=</span><span style=\"color: #BA2121\">&quot;int32&quot;</span>), y: R<span style=\"color: #AA22FF; font-weight: bold\">.</span>Tensor((<span style=\"color: #008000\">8</span>, <span style=\"color: #008000\">8</span>), dtype<span style=\"color: #AA22FF; font-weight: bold\">=</span><span style=\"color: #BA2121\">&quot;int32&quot;</span>), bias: R<span style=\"color: #AA22FF; font-weight: bold\">.</span>Tensor((<span style=\"color: #008000\">8</span>,), dtype<span style=\"color: #AA22FF; font-weight: bold\">=</span><span style=\"color: #BA2121\">&quot;int32&quot;</span>)) <span style=\"color: #AA22FF; font-weight: bold\">-&gt;</span> R<span style=\"color: #AA22FF; font-weight: bold\">.</span>Tensor((<span style=\"color: #008000\">32</span>, <span style=\"color: #008000\">8</span>), dtype<span style=\"color: #AA22FF; font-weight: bold\">=</span><span style=\"color: #BA2121\">&quot;int32&quot;</span>):\n",
       "        <span style=\"color: #008000; font-weight: bold\">with</span> R<span style=\"color: #AA22FF; font-weight: bold\">.</span>dataflow():\n",
       "            lv0: R<span style=\"color: #AA22FF; font-weight: bold\">.</span>Tensor((<span style=\"color: #008000\">32</span>, <span style=\"color: #008000\">8</span>), dtype<span style=\"color: #AA22FF; font-weight: bold\">=</span><span style=\"color: #BA2121\">&quot;int32&quot;</span>) <span style=\"color: #AA22FF; font-weight: bold\">=</span> R<span style=\"color: #AA22FF; font-weight: bold\">.</span>matmul(x, y, out_dtype<span style=\"color: #AA22FF; font-weight: bold\">=</span><span style=\"color: #BA2121\">&quot;int32&quot;</span>)\n",
       "            lv1: R<span style=\"color: #AA22FF; font-weight: bold\">.</span>Tensor((<span style=\"color: #008000\">32</span>, <span style=\"color: #008000\">8</span>), dtype<span style=\"color: #AA22FF; font-weight: bold\">=</span><span style=\"color: #BA2121\">&quot;int32&quot;</span>) <span style=\"color: #AA22FF; font-weight: bold\">=</span> R<span style=\"color: #AA22FF; font-weight: bold\">.</span>add(lv0, bias)\n",
       "            lv2: R<span style=\"color: #AA22FF; font-weight: bold\">.</span>Tensor((<span style=\"color: #008000\">32</span>, <span style=\"color: #008000\">8</span>), dtype<span style=\"color: #AA22FF; font-weight: bold\">=</span><span style=\"color: #BA2121\">&quot;int32&quot;</span>) <span style=\"color: #AA22FF; font-weight: bold\">=</span> R<span style=\"color: #AA22FF; font-weight: bold\">.</span>clip(lv1, R<span style=\"color: #AA22FF; font-weight: bold\">.</span>prim_value(<span style=\"color: #AA22FF; font-weight: bold\">-</span><span style=\"color: #008000\">128</span>), R<span style=\"color: #AA22FF; font-weight: bold\">.</span>prim_value(<span style=\"color: #008000\">127</span>))\n",
       "            R<span style=\"color: #AA22FF; font-weight: bold\">.</span>output(lv2)\n",
       "        <span style=\"color: #008000; font-weight: bold\">return</span> lv2\n",
       "</pre></div>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "mod.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "matmul = is_op(\"relax.matmul\")(wildcard(), wildcard())\n",
    "matmul_add = is_op(\"relax.add\")(matmul, wildcard())\n",
    "pattern = matmul_add | is_op(\"relax.clip\")(matmul_add, wildcard(), wildcard())\n",
    "\n",
    "partitioned = relax.transform.FuseOpsByPattern([(\"orclip\", pattern)])(mod)\n",
    "func_names = [name.name_hint for (name, _) in partitioned.functions.items()]\n",
    "assert \"fused_relax_matmul_relax_add_relax_clip\" in func_names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "ai",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
